﻿using memo.entity.VO;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.IdentityModel.Tokens;
using StackExchange.Redis;

namespace memo.Controllers; 

[ApiController]
[Route("[controller]")]
public class RedisController : ControllerBase
{
    private readonly IDistributedCache _cache;
    private readonly IDatabase _redisDb;

    public RedisController(IDistributedCache c, IConnectionMultiplexer r) {
        _cache = c; // 分布式缓存客户端
        _redisDb = r.GetDatabase(); // 原生Redis客户端
    }

    // 添加/更新字符串
    [HttpPost("addString")]
    public async Task<object> SetString([FromBody] KeyValuePair<string, string> kv)
    {
        // await _cache.SetStringAsync(kv.Key, kv.Value);
        // return Result<object>.Success();
        
        //使用原生 API 存储纯字符串
        var res = await _redisDb.StringSetAsync(kv.Key, kv.Value);
        return res ? Result<object>.Success() : Result<object>.Fail("新增键值对失败");
    }
    
    // 添加/更新字符串（带有过期时间）
    [HttpPost("addStringWithExpire")]
    public async Task<object> SetStringWithExpire([FromBody] KeyValuePair<string, string> kv)
    {
        // await _cache.SetStringAsync(kv.Key, kv.Value, new DistributedCacheEntryOptions() {
        //     AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(10)
        // });
        // return Result<object>.Success();
        
        // 使用原生 API 存储带有过期时间的纯字符串
        //var res = await _redisDb.StringSetAsync(kv.Key, kv.Value, TimeSpan.FromMinutes(1)); // 1分钟过期
        var res = await _redisDb.StringSetAsync(kv.Key, kv.Value, TimeSpan.FromSeconds(20)); // 20秒钟过期
        return res ? Result<object>.Success() : Result<object>.Fail("新增键值对失败");
    }

    // 查询键
    [HttpGet("GetValue/{key}")]
    public async Task<object> GetString(string key)
    {
        // var value = await _cache.GetStringAsync(key);
        // return !value.IsNullOrEmpty() ? Result<object>.Success(value) : Result<object>.Fail("未找到以:【" + key + "】命名的键，无效的键名");
        
        // 使用原生 API 查询key
        var value = await _redisDb.StringGetAsync(key);
        return value.HasValue ? Result<object>.Success(value.ToString()) : Result<object>.Fail("未找到该键，无效的键名");
    }

    // 删除键
    [HttpDelete("del/{key}")]
    public async Task<object> Remove(string key)
    {
        // await _cache.RemoveAsync(key);
        // return Result<object>.Success();
        
        // 使用原生 API 删除key
        var res = await _redisDb.KeyDeleteAsync(key);
        return res ? Result<object>.Success() : Result<object>.Fail("删除键失败");
    }
    
    
    // 设置set集合
    [HttpPost("addSet")]
    public async Task<object> SetAdd([FromBody] KeyValuePair<string, string> kv) {
        var res = await _redisDb.SetAddAsync(kv.Key, kv.Value);
        return res ? Result<object>.Success() : Result<object>.Fail("Set集合新增值失败");
    }
    
    // 获取set集合
    [HttpGet("getSet/{key}")]
    public async Task<object> GetSet(string key) {
        var res = await _redisDb.SetMembersAsync(key);
        if (!(res.Length > 0)) {
            return Result<object>.Fail("未找到该键，无效的键名");
        }

        // 将 RedisValue[] 转换为 string[]
        var values = Array.ConvertAll(res, v => v.ToString());
        return Result<object>.Success(values);
    }
    
    // 设置zet集合
    [HttpPost("addZet")]
    public async Task<object> ZetAdd([FromBody] KeyValuePair<string, string> kv) {
        var timestamp = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); // 获取当前时间戳
        var res = await _redisDb.SortedSetAddAsync(kv.Key, kv.Value, timestamp);
        return res ? Result<object>.Success() : Result<object>.Fail("Zet集合新增值失败");
    }
}